﻿using System;
using System.IO;

namespace Microsoft.Xna.Framework.Audio
{
	internal class AudioFormat
	{
		// Fields
		public readonly int AvgBytesPerSec;
		public readonly short BitsPerSample;
		public readonly short BlockAlign;
		public readonly short Channels;
		public readonly short FormatTag;
		public readonly byte[] RawBuffer;
		public readonly int SampleRate;

		// Methods
		public AudioFormat(byte[] buffer)
		{
			BinaryReader reader = new BinaryReader(new MemoryStream(buffer));
			this.FormatTag = reader.ReadInt16();
			this.Channels = reader.ReadInt16();
			this.SampleRate = reader.ReadInt32();
			this.AvgBytesPerSec = reader.ReadInt32();
			this.BlockAlign = reader.ReadInt16();
			this.BitsPerSample = reader.ReadInt16();
			reader.Close();

			reader = new BinaryReader(new MemoryStream(buffer));
			byte[] buffer2 = buffer;
			if (buffer.Length < 0x12)
			{
				buffer2 = new byte[Math.Max(0x12, buffer.Length)];
			}
			BinaryWriter writer = new BinaryWriter(new MemoryStream(buffer));
			writer.Write(Byteswap(reader.ReadInt16()));
			writer.Write(Byteswap(reader.ReadInt16()));
			writer.Write(Byteswap(reader.ReadInt32()));
			writer.Write(Byteswap(reader.ReadInt32()));
			writer.Write(Byteswap(reader.ReadInt16()));
			writer.Write(Byteswap(reader.ReadInt16()));
			reader.Close();
			writer.Close();
			this.RawBuffer = buffer2;
		}

		#region Internal Methods
		internal static int Byteswap(int value)
		{
			if (!BitConverter.IsLittleEndian)
			{
				value = (((value >> 0x18) | (value << 0x18)) | ((value & 0xff00) << 8)) | ((value & 0xff0000) >> 8);
			}
			return value;
		}

		internal static short Byteswap(short value)
		{
			if (!BitConverter.IsLittleEndian)
			{
				value = (short)(((value & 0xff00) >> 8) | ((value & 0xff) << 8));
			}
			return value;
		}
		#endregion

		public static AudioFormat Create(int sampleRate, AudioChannels channels, short bitDepth)
		{
			byte[] buffer = new byte[0x12];
			BinaryWriter writer = new BinaryWriter(new MemoryStream(buffer));
			writer.Write((short)1);
			writer.Write((short)channels);
			writer.Write(sampleRate);
			writer.Write((int)(((sampleRate * bitDepth) / 8) * ((short)channels)));
			writer.Write((short)((((short)channels) * bitDepth) / 8));
			writer.Write(bitDepth);
			writer.Write((short)0);
			writer.Close();

			return new AudioFormat(buffer);
		}

		public TimeSpan DurationFromSize(int sizeInBytes)
		{
			int num = sizeInBytes / this.BlockAlign;
			return TimeSpan.FromMilliseconds((double) ((num * 1000f) / ((float) this.SampleRate)));
		}

		public bool IsAligned(int value)
		{
			return ((value % this.BlockAlign) == 0);
		}

		public int SizeFromDuration(TimeSpan duration)
		{
			int num = (int) (duration.TotalMilliseconds * (((float) this.SampleRate) / 1000f));
			return ((num + (num % this.Channels)) * this.BlockAlign);
		}
	}
}
